package pl.edu.pw.MidEmu.UI.Components;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.io.File;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

import pl.edu.pw.MidEmu.Base.Components.BaseFrame;
import pl.edu.pw.MidEmu.Common.Consts;
import pl.edu.pw.MidEmu.Common.Models.EthernetInterfaceModel;
import pl.edu.pw.MidEmu.Common.Models.MidasModel;
import pl.edu.pw.MidEmu.Logic.ProcessHandler;
import pl.edu.pw.MidEmu.UI.Controllers.MidasLoaderController;
import pl.edu.pw.MidEmu.UI.Views.MidasLoaderView;

/**
 * Frame with GUI for launching MIDAS platform instance
 * @author Mateusz Starodab
 *
 */
public class MidasLoaderFrame extends BaseFrame<JDialog, MidasLoaderController> implements MidasLoaderView
{
	private ButtonGroup bgNodeType;
	private JButton btnCancel;
	private JButton btnOK;

	private JButton btnPickBinDir;
	private boolean canRun = true;

	private JFileChooser fchChooseBinDirPath;
	private JLabel lblBinDir;
	private JLabel lblClassName;
	private JLabel lblClassPath;

	private JLabel lblCommandLineParameters;
	private JLabel lblEthernetInterface;
	private JLabel lblNodeType;
	private JComboBox lbxEthernetInterface;

	private MidasComponent parent;
	private JPanel pnlCenter;
	private JPanel pnlMain;
	private JPanel pnlSouth;

	private JRadioButton rbCentralNode;
	private JRadioButton rbUserNode;

	private JTextField tbxBinDir;

	private JTextField tbxClassName;

	private JTextArea tbxClassPath;
	private JTextArea tbxCommandLineParameters;

	public MidasLoaderFrame(MidasComponent midasComponent)
	{
		this.parent = midasComponent;

		MidasLoaderController controller = new MidasLoaderController();
		controller.setView(this);
		setController(controller);
		JDialog frame = new JDialog();
		setComponent(frame);

		getComponent().setTitle(Consts.MainFrame_Title + " - " + Consts.MidasLoaderFrame_Title);
		getComponent().setSize(480, 600);
		getComponent().setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		getComponent().setModal(true);

		pnlMain = new JPanel();
		pnlMain.setLayout(new BorderLayout());

		pnlSouth = new JPanel();
		pnlSouth.setLayout(new FlowLayout());

		btnOK = new JButton(Consts.MidasLoaderFrame_StartMidas);
		btnOK.setName(Consts.MidasLoaderFrame_StartMidas);
		btnOK.addActionListener(getController());

		btnCancel = new JButton(Consts.MidasLoaderFrame_CancelButton);
		btnCancel.setName(Consts.MidasLoaderFrame_CancelButton);
		btnCancel.addActionListener(getController());

		pnlCenter = new JPanel();
		pnlCenter.setLayout(new FlowLayout(FlowLayout.LEFT));

		pnlCenter.setBorder(BorderFactory.createTitledBorder(Consts.MidasLoaderFrame_Caption));

		JPanel pnlBinDirLocation = new JPanel(new BorderLayout());
		JPanel pnlBinDir1Location = new JPanel(new FlowLayout(FlowLayout.LEFT));
		JPanel pnlBinDir2Location = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		lblBinDir = new JLabel(Consts.MidasLoaderFrame_BinDirLabel);
		tbxBinDir = new JTextField(40);
		lblBinDir.setLabelFor(pnlBinDirLocation);
		btnPickBinDir = new JButton(Consts.MidasLoaderFrame_BinkDirButton);
		btnPickBinDir.setName(Consts.MidasLoaderFrame_BinkDirButton);
		btnPickBinDir.addActionListener(getController());

		pnlBinDir1Location.add(tbxBinDir);
		pnlBinDir2Location.add(btnPickBinDir);

		pnlBinDirLocation.add(pnlBinDir1Location, BorderLayout.CENTER);
		pnlBinDirLocation.add(pnlBinDir2Location, BorderLayout.SOUTH);

		pnlCenter.add(lblBinDir);
		pnlCenter.add(pnlBinDirLocation);

		tbxClassName = new JTextField(40);
		lblClassName = new JLabel(Consts.MidasLoaderFrame_ClassNameLabel);
		lblClassName.setLabelFor(tbxClassName);

		tbxCommandLineParameters = new JTextArea(3, 40);
		tbxCommandLineParameters.setBorder(tbxClassName.getBorder());
		tbxCommandLineParameters.setLineWrap(true);
		lblCommandLineParameters = new JLabel(Consts.MidasLoaderFrame_CommandLineLabel);
		lblCommandLineParameters.setLabelFor(tbxCommandLineParameters);

		tbxClassPath = new JTextArea(10, 40);
		tbxClassPath.setBorder(tbxClassName.getBorder());
		tbxClassPath.setLineWrap(true);
		lblClassPath = new JLabel(Consts.MidasLoaderFrame_ClassPathLabel);
		lblClassPath.setLabelFor(tbxClassPath);

		pnlCenter.add(lblClassName);
		pnlCenter.add(tbxClassName);

		pnlCenter.add(lblCommandLineParameters);
		pnlCenter.add(tbxCommandLineParameters);

		pnlCenter.add(lblClassPath);
		pnlCenter.add(tbxClassPath);

		JPanel pnlNorth = new JPanel();
		pnlNorth.setLayout(new FlowLayout(FlowLayout.LEFT));
		pnlNorth.setBorder(BorderFactory.createTitledBorder(Consts.MidasLoaderFrame_CaptionNode));
		pnlNorth.setPreferredSize(new Dimension(450, 100));

		lblNodeType = new JLabel(Consts.MidasLoaderFrame_LabelNodeType);
		bgNodeType = new ButtonGroup();
		rbCentralNode = new JRadioButton(Consts.MidasLoaderFrame_RadioCentral);
		rbCentralNode.setName(Consts.MidasLoaderFrame_RadioCentral);
		rbCentralNode.setSelected(true);
		bgNodeType.add(rbCentralNode);
		rbUserNode = new JRadioButton(Consts.MidasLoaderFrame_RadioUser);
		rbUserNode.setName(Consts.MidasLoaderFrame_RadioUser);
		rbUserNode.setPreferredSize(new Dimension(210, 12));
		bgNodeType.add(rbUserNode);
		if (parent.isCentralNodeRunning())
		{
			rbCentralNode.setEnabled(false);
			rbUserNode.setSelected(true);
		}
		else
		{
			rbUserNode.setEnabled(false);
			rbCentralNode.setSelected(true);
		}

		lblEthernetInterface = new JLabel(Consts.MidasLoaderFrame_LabelEthernet);
		DefaultComboBoxModel comboModel = new DefaultComboBoxModel();
		getController().fillModel(comboModel);
		lbxEthernetInterface = new JComboBox(comboModel);
		lblEthernetInterface.setLabelFor(lbxEthernetInterface);
		lbxEthernetInterface.addActionListener(getController());
		lbxEthernetInterface.setName(Consts.MidasLoaderFrame_LabelEthernet);

		pnlNorth.add(lblNodeType);
		pnlNorth.add(rbCentralNode);
		pnlNorth.add(rbUserNode);
		pnlNorth.add(lblEthernetInterface);
		pnlNorth.add(lbxEthernetInterface);

		pnlMain.add(pnlNorth, BorderLayout.NORTH);

		pnlMain.add(pnlCenter, BorderLayout.CENTER);

		pnlSouth.add(btnOK);
		pnlSouth.add(btnCancel);
		pnlMain.add(pnlSouth, BorderLayout.SOUTH);

		getComponent().setContentPane(pnlMain);

		MidasModel model = MidasModel.load();
		if (model != null)
		{
			tbxClassName.setText(model.getClassName());
			tbxCommandLineParameters.setText(model.getParameters());
			tbxBinDir.setText(model.getBinariesDirectory());
			tbxClassPath.setText(model.getClassPath());
		}

		fchChooseBinDirPath = new JFileChooser();
		fchChooseBinDirPath.setMultiSelectionEnabled(false);
		fchChooseBinDirPath.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

		getComponent().getRootPane().setDefaultButton(btnOK);
	}

	public boolean canRun()
	{
		return canRun;
	}

	@Override
	public void dispose()
	{
		getComponent().setVisible(false);
		getComponent().dispose();
	}

	@Override
	public String getBinariesDir()
	{
		return tbxBinDir.getText();
	}

	@Override
	public String getCentralNodeID()
	{
		return parent.getCentralNodeModel().getName();
	}

	@Override
	public String getCentralNodeIP()
	{
		return parent.getCentralNodeIP();
	}

	@Override
	public String getClassName()
	{
		return tbxClassName.getText();
	}

	@Override
	public EthernetInterfaceModel getEthernetInterface()
	{
		return (EthernetInterfaceModel) lbxEthernetInterface.getSelectedItem();
	}

	@Override
	public List<EthernetInterfaceModel> getFreeInterfaces()
	{
		return parent.getFreeInterfaces();
	}

	@Override
	public String getLibPath()
	{
		return tbxClassPath.getText();
	}

	@Override
	public String getParams()
	{
		return tbxCommandLineParameters.getText();
	}

	@Override
	public Boolean isCentralNode()
	{
		return rbCentralNode.getModel().isSelected();
	}

	@Override
	public void registerMidas(MidasModel model, ProcessHandler handler)
	{
		parent.getController().registerMidas(model, handler);
	}

	@Override
	public void reportNoFreeInterfaces()
	{
		JOptionPane.showMessageDialog(getComponent(), "Can't run new midas instance because there, are no free interfaces.\nPlease add additional interfaces through Settings/Network menu.", "No free interfaces", JOptionPane.ERROR_MESSAGE);
		canRun = false;
	}

	public void reportValidationErrors()
	{
		JOptionPane.showMessageDialog(getComponent(), "MIDAS environment configuration is invalid.\nMake sure you fill all fields, \nand node name you've entered is unique", "Invalid configuration", JOptionPane.ERROR_MESSAGE);
	}

	@Override
	public void showPickupBinariesDirExecDialog()
	{
		fchChooseBinDirPath.showOpenDialog(getComponent());
		File selectedFile = fchChooseBinDirPath.getSelectedFile();
		if (selectedFile != null)
			tbxBinDir.setText(selectedFile.getAbsolutePath());
	}

	public boolean validateMIDAS()
	{
		if (getClassName().equals(""))
			return false;
		if (getBinariesDir().equals(""))
			return false;
		if (getLibPath().equals(""))
			return false;
		return true;
	}
}
